﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace HelloXNA2.Component.MyCustom.FourPolygon
{
    public class PolygonHelper
    {
        protected VertexBuffer vb;

        protected Texture2D texture;

        protected BasicEffect be;
        protected Matrix world;
        public Matrix World
        {
            get { return world; }
            set { world = value; }
        }

        private GraphicsDevice g;

        public PolygonHelper(GraphicsDevice g, Vector3[] corners, int[][] faces, Color color)
        {
            this.g = g;
            VertexPositionNormalTexture[] vertices = CreateVertices(corners, faces);
            vb = new VertexBuffer(g, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
            vb.SetData(0, vertices, 0, vertices.Length, VertexPositionNormalTexture.VertexDeclaration.VertexStride);
            texture = new Texture2D(g, 1, 1, false, SurfaceFormat.Color);
            texture.SetData<Color>(new Color[1] { color });
            be = new BasicEffect(g);
            be.EnableDefaultLighting(); // 使用默认光源效果            
            be.LightingEnabled = true;
            be.Texture = texture;
            be.TextureEnabled = true;
        }

        public void Draw(Matrix view, Matrix projection)
        {
            g.SetVertexBuffer(vb);
            be.World = world;
            be.View = view;
            be.Projection = projection;
            be.CurrentTechnique.Passes[0].Apply();
            g.DrawPrimitives(PrimitiveType.TriangleList, 0, vb.VertexCount / 3);
        }

        private VertexPositionNormalTexture[] CreateVertices(Vector3[] corners, int[][] faces)
        {
            int triangleCount = 0;
            // 组成一个面所用的顶点数-2就是所用的三角形数
            foreach (int[] face in faces)
            {
                triangleCount += face.Length - 2;
            }
            // 用到的顶点数 = 用到的三角形数 * 3            
            VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[triangleCount * 3];
            int i = 0;
            foreach (int[] face in faces)
            {
                // 定义每个三角形的顶点信息                
                for (int j = 0; j < face.Length - 2; j++)
                {
                    vertices[i++] = new VertexPositionNormalTexture(corners[face[0]], Vector3.Zero, Vector2.Zero);
                    vertices[i++] = new VertexPositionNormalTexture(corners[face[j + 1]], Vector3.Zero, Vector2.Zero);
                    vertices[i++] = new VertexPositionNormalTexture(corners[face[j + 2]], Vector3.Zero, Vector2.Zero);
                }
                Vector3 vectorA = vertices[i - 1].Position - vertices[i - 3].Position;
                Vector3 vectorB = vertices[i - 1].Position - vertices[i - 2].Position;
                Vector3 normal = Vector3.Cross(vectorB, vectorA);
                for (int j = 0; j < (face.Length - 2) * 3; j++)
                    vertices[i - 1 - j].Normal = normal;
            }

            return vertices;
        }
    }
}
